package com.sl.config;

/**
 * @author: weilai
 * @date: 2020/2/10
 * @description:
 */
import com.sl.entity.Result;
import com.sl.entity.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.hibernate.validator.internal.engine.path.PathImpl;

import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public Result badArgumentHandler(IllegalArgumentException e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"没有权限");
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public Result badArgumentHandler(MethodArgumentTypeMismatchException e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"方法参数类型不匹配");
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public Result badArgumentHandler(MissingServletRequestParameterException e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"缺少Servlet请求参数");
    }
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public Result badArgumentHandler(NullPointerException e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"空指针");
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public Result badArgumentHandler(HttpMessageNotReadableException e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"请检查请求方式POST，携带请求体{}");
    }

    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    @ResponseBody
    public Result badArgumentHandler(HttpMediaTypeNotSupportedException e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"媒体类型不支持");
    }
    @ExceptionHandler(AuthorizationException.class)
    @ResponseBody
    public Result badArgumentHandler(AuthorizationException e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"全局异常捕获：没有授权。也可能代码没写好");
    }
    @ExceptionHandler(ValidationException.class)
    @ResponseBody
    public Result badArgumentHandler(ValidationException e) {
        log.error(e.getMessage(),e);
        if (e instanceof ConstraintViolationException) {
            ConstraintViolationException exs = (ConstraintViolationException) e;
            Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
            for (ConstraintViolation<?> item : violations) {
                String message = ((PathImpl) item.getPropertyPath()).getLeafNode().getName() + item.getMessage();
                return new Result(false, StatusCode.ERROR,"验证异常");
            }
        }
        return new Result(false, StatusCode.ERROR,"发生错误，请检查参数或联系后台");
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result seriousHandler(Exception e) {
        log.error(e.getMessage(),e);
        return new Result(false, StatusCode.ERROR,"发生错误，请检查参数或联系后台");
    }
}
